import 'package:device_info/device_info.dart';
import 'package:mmkv/mmkv.dart';
import 'package:myapp/app/data/api/providers/api_provider.dart';
import 'package:get/get.dart';
import 'package:myapp/app/data/db/app_database.dart';
import 'package:myapp/app/data/entities/banner_model.dart';
import 'package:myapp/app/data/entities/bw_realtor_model.dart';
import 'package:myapp/app/data/entities/user_model.dart';
import 'package:myapp/app/data/user_manager.dart';
import 'package:myapp/app/utils/main_const.dart';
import 'package:myapp/app/utils/platform_utils.dart';


abstract class ICommRepository {

  Future<BwRealtor> getBwRealtor();

  Future<String> deviceRegister();

  String? getToken();

  void clearToken();

  Future<List<Banner>> getBannerList();

  Future<User> login(String username, String password);

  Future<User> tokenLogin();

  Future<void> loadLocalUser();

}



class CommRepository implements ICommRepository {

  static const String _TOKEN = MainConst.MMKV_TOKEN;

  final _apiProvider = Get.find<ApiProvider>();

  AppDatabase? _appDatabase;

  @override
  Future<BwRealtor> getBwRealtor() {
    return _apiProvider.getBwRealtor();
  }

  @override
  void clearToken() {
    MMKV.defaultMMKV().removeValue(_TOKEN);
  }

  @override
  String? getToken() {
    return MMKV.defaultMMKV().decodeString(_TOKEN);
  }

  @override
  Future<String> deviceRegister() async {
    var plugin  = DeviceInfoPlugin();
    if(PlatformUtils.isAndroid) {
      var info = await plugin.androidInfo;
      var token = await _apiProvider.deviceRegister(info.device, info.androidId, info.version.release);
      MMKV.defaultMMKV().encodeString(_TOKEN, token);
      return token;
    } else if(PlatformUtils.isIos) {
      var info = await plugin.iosInfo;
      var token = await _apiProvider.deviceRegister(info.name, info.identifierForVendor, info.model);
      MMKV.defaultMMKV().encodeString(_TOKEN, token);
      return token;
    }
    return "";
  }

  Map<String, dynamic> _readAndroidBuildData(AndroidDeviceInfo build) {
    return <String, dynamic>{
      'version.securityPatch': build.version.securityPatch,
      'version.sdkInt': build.version.sdkInt,
      'version.release': build.version.release,
      'version.previewSdkInt': build.version.previewSdkInt,
      'version.incremental': build.version.incremental,
      'version.codename': build.version.codename,
      'version.baseOS': build.version.baseOS,
      'board': build.board,
      'bootloader': build.bootloader,
      'brand': build.brand,
      'device': build.device,
      'display': build.display,
      'fingerprint': build.fingerprint,
      'hardware': build.hardware,
      'host': build.host,
      'id': build.id,
      'manufacturer': build.manufacturer,
      'model': build.model,
      'product': build.product,
      'supported32BitAbis': build.supported32BitAbis,
      'supported64BitAbis': build.supported64BitAbis,
      'supportedAbis': build.supportedAbis,
      'tags': build.tags,
      'type': build.type,
      'isPhysicalDevice': build.isPhysicalDevice,
      'androidId': build.androidId,
      'systemFeatures': build.systemFeatures,
    };
  }

  @override
  Future<User> login(String username, String password) async {
    var user = await _apiProvider.login(username, password);
    await _initDatabase();
    await _appDatabase?.userDao.insertUser(user);
    UserManager.instance.initUser(user);
    return user;
  }

  @override
  Future<User> tokenLogin() async {
    var user = await _apiProvider.tokenLogin();
    await _initDatabase();
    await _appDatabase?.userDao.insertUser(user);
    UserManager.instance.initUser(user);
    return user;
  }

  @override
  Future<void> loadLocalUser() async {
    await _initDatabase();
    var user = await _appDatabase?.userDao.getUser();
    if(user != null) {
      UserManager.instance.initUser(user);
    }
  }

  Future<void> _initDatabase() async {
    if(_appDatabase == null) {
      _appDatabase = await $FloorAppDatabase.databaseBuilder('app_database.db').build();
    }
  }

  @override
  Future<List<Banner>> getBannerList() async {
    return await _apiProvider.getBannerList();
  }

}
